package com.fks.fks_service.utils;


import com.fks.fks_service.pojo.IPAddressDomain;
import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.exception.GeoIp2Exception;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description: ip 相关工具类
 * @author sunyalong
 */
@Slf4j
public class IpUtil {

    public static DatabaseReader reader = null;

    public static Lock lock = new ReentrantLock();

    public static String getIpAddr(HttpServletRequest request){
        String ip = request.getHeader("X-Real-IP");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

    /**
     * 初始化省市区内容到内存
     *
     * @param inputStream
     * @throws IOException
     */
    private static void init(InputStream inputStream) throws IOException {
        try {
            lock.lock();
            // 读取数据库内容
            reader = new DatabaseReader.Builder(inputStream).build();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    /**
     * 通过一个 ip地址查询这个ip地址 代表 那个城市 使用方法参考	 )
     * @param inputStream 给一个ip查询的文件
     * @param inetAddress	ip的一个包装 InetAddress.getByName("171.108.233.157");
     * @return
     * @throws IOException
     * @throws GeoIp2Exception
     */
    public static IPAddressDomain findCityByIp(InputStream inputStream, InetAddress inetAddress) throws IOException, GeoIp2Exception, GeoIp2Exception {
        // 返回对象
        IPAddressDomain ipAddressDomain = new IPAddressDomain();
        try {
            if(reader == null){
                init(inputStream);
            }

            CityResponse response = reader.city(inetAddress);
            // 获取国家信息
            Country country = response.getCountry();

            ipAddressDomain.setCountrySimpleCode(country.getIsoCode());
            ipAddressDomain.setCountryEnglishName(country.getName());
            ipAddressDomain.setIp(inetAddress.getHostAddress());
            // 获取省份
            Subdivision subdivision = response.getMostSpecificSubdivision();
            ipAddressDomain.setSubdivisionSimpleCode(subdivision.getIsoCode());
            ipAddressDomain.setSubdivisionEnglisName(subdivision.getName());

            // 获取城市
            City city = response.getCity();
            ipAddressDomain.setCityEnglishName(city.getName());
            ipAddressDomain.setCitySimpleCode(String.valueOf(city.getGeoNameId()));

            Postal postal = response.getPostal();
            ipAddressDomain.setCitySimpleCode(postal.getCode());

            Location location = response.getLocation();
            ipAddressDomain.setLatitude(location.getLatitude().toString());
            ipAddressDomain.setLongitude(location.getLongitude().toString());
            return ipAddressDomain;
        }catch (Exception e ){
            log.info("ip异常");
            return ipAddressDomain;
        }
    }

}
